package com.share.module.sys.user.service;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.module.sys.user.entity.User;
import com.share.module.sys.user.vo.UserPageQueryPageQueryVO;
import com.stock.common.exception.BusinessException;
import com.stock.common.lang.StringUtils;
import com.stock.common.utils.MD5Util;
import com.share.common.utils.TokenUtil;
import com.share.module.sys.menu.service.MenuService;
import com.share.module.sys.user.dto.UserNameAndPasswordDTO;
import com.share.module.sys.user.dto.UserDTO;
import com.share.module.sys.user.listener.UploadUserDataListener;
import com.share.module.sys.user.vo.UploadUserVO;
import com.share.module.sys.menu.entity.Menu;
import com.share.module.sys.role.dao.RoleDAO;
import com.share.module.sys.rolemenu.dao.RoleMenuDAO;
import com.share.module.sys.user.dao.UserDAO;

import com.stock.mybatisplus.utils.PageUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author lijy
 * @since 2023-04-04
 */
@Service
public class UserService extends ServiceImpl<UserDAO, User> {

    @Resource
    private RoleDAO roleDAO;

    @Resource
    private RoleMenuDAO roleMenuDAO;

    @Resource
    private MenuService menuService;

    public PageUtils page(UserPageQueryPageQueryVO vo) {
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotBlank(vo.getUsername()), User::getUsername, vo.getUsername());
        wrapper.like(StringUtils.isNotEmpty(vo.getEmail()), User::getEmail, vo.getEmail());
        wrapper.like(StringUtils.isNotEmpty(vo.getAddress()), User::getAddress, vo.getAddress());
        wrapper.orderByDesc(User::getId);
        IPage<User> page = super.page(new Page<>(vo.getCurrPage(), vo.getSize()), wrapper);
        return new PageUtils(page);
    }

    public void upload(MultipartFile file, UserService userService) throws IOException {
        EasyExcel.read(file.getInputStream(),
                UploadUserVO.class,
                new UploadUserDataListener(userService))
                .sheet()
                .doRead();
    }

    public UserDTO login(UserNameAndPasswordDTO user) {
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(User::getUsername, user.getUsername());
        User one = getOne(wrapper);

        UserDTO userDTO = new UserDTO();

        userDTO.setUsername(user.getUsername());
        if (one != null) {
            if (!one.getPassword().equals(MD5Util.string2MD5(user.getPassword()))) {
                throw new BusinessException("密码错误！");
            }
            userDTO.setNickName(one.getNickname());
            userDTO.setAvatarUrl(one.getAvatarUrl());
            userDTO.setRole(one.getRole());
            userDTO.setMenus(getRoleMenus(one.getRole()));
            userDTO.setToken(TokenUtil.genToken(one.getId().toString(), one.getPassword()));
            return userDTO;
        }

        throw new BusinessException("用户名或密码错误");
    }

    private List<Menu> getRoleMenus(String role) {
        Integer roleId = roleDAO.selectByFlag(role);
        // 当前角色的所有菜单id集合
        List<Integer> menuIds = roleMenuDAO.selectByRoleId(roleId);

        // 查出系统所有菜单
        List<Menu> all = menuService.findAll("");
        // new一个最后筛选完成之后的list
        List<Menu> target = new ArrayList<>();
        // 筛选当前用户角色菜单
        for (Menu menu : all) {
            if (menuIds.contains(menu.getId())) {
                target.add(menu);
            }
            List<Menu> children = menu.getChildren();
            // removeIf() 移除children里面不在menuIds集合中的元素
            children.removeIf(child -> !menuIds.contains(child.getId()));
        }
        return target;
    }

    public void register(UserNameAndPasswordDTO user) {
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(User::getUsername, user.getUsername());
        User one = getOne(wrapper);
        if (one != null) {
            throw new BusinessException("用户名已存在");
        }

        one = new User();
        one.setUsername(user.getUsername());
        one.setPassword(MD5Util.string2MD5(user.getPassword()));
        save(one);
    }

}
